package model;

import controller.Move;
import java.util.ArrayList;

/**
 *
 * @author Robert EA
 */
public class Checkerboard {
    //private Square having;
  
    private Square tabSquare[][];   // tab of square
    private int size = 10;          // Number of square on a line/column
    private int line;               // number of the line
    private int column;             // number of the column
    private boolean isSelected;     // If a square is already selected
    // EDIT Pour les tests seulement. Designe le joueur en cours
    private int player; // 1 or 2
    private int nbPiecesPlayer1;    // Nb of pieces player 1 actually have
     private int nbPiecesPlayer2;   // Nb of pieces player 2 actually have
    // State of a square
    public static final int EMPTY = 0;
    public static final int P1_PAWN = 1;
    public static final int P1_QUEEN = 2;
    public static final int P2_PAWN = 3;
    public static final int P2_QUEEN = 4;
    public static final int INVALID = 5;

    private int[] tabPlayablePieces; // Contains id of all Playable Square
    private int nbPlayablePieces;
    private int idSelectedSquare; // Id of the currently selected square
    private ArrayList<Move> listCurrentMoves = null;
    private Move currentMove = null;

    /**
     * Checkerboard() :
     * Create a 2-dimension table of Squares
     */
    public Checkerboard() {
        tabPlayablePieces = new int[20];
        tabSquare = new Square[size][size];
        int i, j;
        for (i = 0; i < size; i++) {
            for (j = 0; j < size; j++) {
                tabSquare[i][j] = new Square();
            }
        }
    }

    public Square[][] getTabSquare() {
        return tabSquare;
    }

    public void setTabSquare(Square[][] tabSquare) {
        this.tabSquare = tabSquare;
    }

    public Square getSquare(int i, int j) {
        return tabSquare[i][j];
    }
    //public Square setSquare(int i, int j) {this.tabSquare[i][j] = ;}

    public int getSize() {
        return size;
    }

    public void setSize(int size) {
        this.size = size;
    }

    public int getLine() {
        return line;
    }

    public void setLine(int line) {
        this.line = line;
    }

    public int getColumn() {
        return column;
    }

    public void setColumn(int column) {
        this.column = column;
    }

    public boolean getIsSelected() {
        return isSelected;
    }

    public void setIsSelected(boolean isSelected) {
        this.isSelected = isSelected;
    }

    public int getPlayer() {
        return player;
    }

    public void setPlayer(int player) {
        this.player = player;
    }

    public int getIdSelectedSquare() {
        return idSelectedSquare;
    }

    public void setIdSelectedSquare(int idSelectedSquare) {
        this.idSelectedSquare = idSelectedSquare;
    }

    public int getNbPlayablePieces() {return nbPlayablePieces;}
    public void setNbPlayablePieces(int nbPlayablePieces) {this.nbPlayablePieces = nbPlayablePieces;}
    public int getValueTabPlayablePieces(int position) {return tabPlayablePieces[position];}
    public void setTabPlayablePieces(int value, int position) {
        boolean already = false; // Used to prevent redundancy except for value -1


        if(value == -1)     // Default value
            this.tabPlayablePieces[position] = value;
        else
                {
            for(int i=0; i<this.tabPlayablePieces.length;i++)
                if(this.tabPlayablePieces[i] == value)  // Value is already in table ==> Get out
                    already = true;


                if(already == false)
                {
                this.tabPlayablePieces[position] = value;
                this.nbPlayablePieces++;
            }
        }



    }

    /**
     * Returns a code for a piece on coordinates (Checkeboard.INVALID if out of bounds)
     * @param x horizontal offset square
     * @param y vertical offset square
     * @return code for a piece on coordinates (Checkeboard.INVALID if out of bounds)
     */
    public int getPiece(int x, int y) {
        int dimension = getSize();
        if (x < dimension && y < dimension && x >= 0 && y >= 0) {
            return getSquare(x, y).getIsOccupied(); //to verify see initSquare()
        }
        return INVALID;
    }

    /**
     * Returns the sequence of pieces in specified direction
     * @param x horizontal position of start point
     * @param y vertical position of start point
     * @param h horizontal coefficient (-1 or +1)
     * @param v vertical coefficient (-1 or +1)
     * @return
     */
    public ArrayList getSequence(int x, int y, int h, int v) {
        ArrayList sequence = new ArrayList();
        int p = INVALID;
        for (int distance = 1;
                (p = getPiece(x + distance * h, y + distance * v)) != INVALID;
                distance++) {
            sequence.add(p);
        }
        return sequence;
    }

    /**
     * Returns the sequence of pieces in specified direction without specified position which will be EMPTY
     * @param x horizontal position of start point
     * @param y vertical position of start point
     * @param h horizontal coefficient (-1 or +1)
     * @param v vertical coefficient (-1 or +1)
     * @param emptyX horizontal position (in checkerboard) of start point
     * @param emptyY vertical position (in checkerboard) of start point
     * @return
     */
    public ArrayList getSequenceWithoutCalling(int emptyX, int emptyY, int x, int y, int h, int v) {
        ArrayList sequence = getSequence(x, y, h, v);
        int dx = (emptyX - x) * h;
        int dy = (emptyY - y) * v;
        if (dx == dy && dx > 0) { //check positive linear dependance and not the same
            sequence.set(dx - 1, EMPTY);
        }
        return sequence;
    }

    /**
     * Tells us whether a Piece is a Dame
     * @param piece
     * @return true if piece is a Dame
     */
    public static boolean isDame(int piece) {
        return (piece == Checkerboard.P1_QUEEN
                || piece == Checkerboard.P2_QUEEN);
    }

    /**
     * Get color of specified Square
     * @param x horizontal offset square
     * @param y vertical offset square
     * @return char containing colour of the specified element or nothing if
     */
    public char getColor(int x, int y) {
        return getSquare(x, y).getColor(); //to verify see initSquare()
    }

    /**
     * Verify x, y is within the range
     * @param x horizontal offset square
     * @param y vertical offset square
     * @return whether the square exists
     */
    public boolean checkBorders(int x, int y) {
        int dimension = getSize();
        if (x >= dimension
                || y >= dimension
                || x < 0
                || y < 0) {
            return false;
        }
        return true;
    }

    /**
     * Returns a player number for a piece
     * @param aPiece
     * @return player identification number (1 or 2), 0 if aPiece is not piece (INVALID or EMPTY)
     */
    public static int getPlayer(int aPiece) {
        return (aPiece == Checkerboard.P1_PAWN || aPiece == Checkerboard.P1_QUEEN) ? 1
                : (aPiece == Checkerboard.P2_PAWN || aPiece == Checkerboard.P2_QUEEN) ? 2
                : 0;
    }

    /**
     * Returns enemy of player
     * @param player
     * @return enemy 0 if player not valid
     */
    public static int getEnemy(int player) {
        return player == 1 ? 2
                : player == 2 ? 1
                : 0;
    }

    /**
     * Set a square to contain a specified piece / EMPTY space
     * @param x horizontal offset square
     * @param y vertical offset square
     * @param piece
     */
    public void setPiece(int x, int y, int piece) {
        getSquare(x, y).setIsOccupied(piece); //to verify see initSquare()
    }

    /**
     * @return the currentMoves
     */
    public ArrayList<Move> getListCurrentMoves() {
        return listCurrentMoves;
    }

    /**
     * @param currentMoves the currentMoves to set
     */
    public void setListCurrentMoves(ArrayList<Move> currentMoves) {
        this.listCurrentMoves = currentMoves;
    }

    /**
     * @return the currentMove
     */
    public Move getCurrentMove() {
        return currentMove;
    }

    /**
     * @param currentMove the currentMove to set
     */
    public void setCurrentMove(Move currentMove) {
        this.currentMove = currentMove;
    }

    /**
     * @return the nbPiecesPlayer1
     */
    public int getNbPiecesPlayer1() {
        return nbPiecesPlayer1;
    }

    /**
     * @param nbPiecesPlayer1 the nbPiecesPlayer1 to set
     */
    public void setNbPiecesPlayer1(int nbPiecesPlayer1) {
        this.nbPiecesPlayer1 = nbPiecesPlayer1;
    }

    /**
     * @return the nbPiecesPlayer2
     */
    public int getNbPiecesPlayer2() {
        return nbPiecesPlayer2;
    }

    /**
     * @param nbPiecesPlayer2 the nbPiecesPlayer2 to set
     */
    public void setNbPiecesPlayer2(int nbPiecesPlayer2) {
        this.nbPiecesPlayer2 = nbPiecesPlayer2;
    }
}